package com.pn.taikao.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.security.MessageDigest;
import java.util.Date;

/**
 * JWT工具类
 * 用于生成和解析JWT Token
 */
@Component
public class JwtUtil {

    private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
    private static final String JWT_ISSUER = "taikao-system"; // JWT签发者

    @Value("${jwt.secret:TaikaoSecureKey256BitsForJWTTokenGenerationAndVerification2024}")
    private String secret;

    @Value("${jwt.expirationSeconds:86400}")
    private long expirationSeconds; // 默认24小时

    private SecretKey secretKey;

    /**
     * 获取密钥（固定密钥，简化处理）
     */
    private SecretKey getKey() {
        if (secretKey != null) {
            return secretKey;
        }

        byte[] keyBytes = secret.getBytes();
        
        // 如果密钥长度不足32字节，使用SHA-256哈希扩展
        if (keyBytes.length < 32) {
            try {
                MessageDigest digest = MessageDigest.getInstance("SHA-256");
                keyBytes = digest.digest(keyBytes);
            } catch (Exception e) {
                logger.error("生成密钥失败", e);
                throw new RuntimeException("JWT密钥初始化失败", e);
            }
        }
        
        secretKey = Keys.hmacShaKeyFor(keyBytes);
        return secretKey;
    }

    /**
     * 生成JWT Token
     * 
     * @param userId 用户ID
     * @param username 用户名
     * @param roleType 角色类型
     * @return JWT Token字符串
     */
    public String generateToken(Long userId, String username, String roleType) {
        long now = System.currentTimeMillis();
        Date issuedAt = new Date(now);
        Date expiresAt = new Date(now + expirationSeconds * 1000);
        
        return Jwts.builder()
                .claim("uid", userId)
                .claim("username", username)
                .claim("role", roleType)
                .setIssuer(JWT_ISSUER)
                .setIssuedAt(issuedAt)
                .setExpiration(expiresAt)
                .signWith(getKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 解析JWT Token
     * 
     * @param token JWT Token字符串
     * @return Claims 对象
     * @throws io.jsonwebtoken.JwtException 如果token无效
     */
    public Claims parseToken(String token) {
        Jws<Claims> jws = Jwts.parserBuilder()
                .setSigningKey(getKey())
                .requireIssuer(JWT_ISSUER)
                .build()
                .parseClaimsJws(token);
        return jws.getBody();
    }

    /**
     * 检查Token是否过期
     * 
     * @param claims Claims对象
     * @return true如果已过期，false如果未过期
     */
    public boolean isTokenExpired(Claims claims) {
        if (claims.getExpiration() == null) {
            return true;
        }
        return claims.getExpiration().before(new Date());
    }

    /**
     * 从Token中获取用户ID
     */
    public Long getUserIdFromToken(String token) {
        try {
            Claims claims = parseToken(token);
            return claims.get("uid", Long.class);
        } catch (Exception e) {
            logger.debug("从Token中获取用户ID失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从Token中获取用户名
     */
    public String getUsernameFromToken(String token) {
        try {
            Claims claims = parseToken(token);
            return claims.get("username", String.class);
        } catch (Exception e) {
            logger.debug("从Token中获取用户名失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 从Token中获取角色
     */
    public String getRoleFromToken(String token) {
        try {
            Claims claims = parseToken(token);
            return claims.get("role", String.class);
        } catch (Exception e) {
            logger.debug("从Token中获取角色失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 验证Token是否有效
     */
    public boolean validateToken(String token) {
        try {
            Claims claims = parseToken(token);
            return !isTokenExpired(claims);
        } catch (Exception e) {
            logger.debug("Token验证失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 刷新Token
     */
    public String refreshToken(String token) {
        try {
            Claims claims = parseToken(token);
            Long userId = claims.get("uid", Long.class);
            String username = claims.get("username", String.class);
            String role = claims.get("role", String.class);
            return generateToken(userId, username, role);
        } catch (Exception e) {
            logger.warn("刷新Token失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 获取Token的剩余有效时间（秒）
     */
    public long getRemainingSeconds(String token) {
        try {
            Claims claims = parseToken(token);
            Date expiration = claims.getExpiration();
            if (expiration == null) {
                return -1;
            }
            long remaining = expiration.getTime() - System.currentTimeMillis();
            return remaining > 0 ? remaining / 1000 : 0;
        } catch (Exception e) {
            return -1;
        }
    }
}
